`timescale  1ns/1ns


module  ethernet_top
(
    input   wire            sys_clk         ,
    input   wire            sys_rst_n       ,   //系统复位,低电平有效
    input   wire            eth_clk         ,   //PHY芯片时钟信号

    
    input   wire            eth_rxdv_r      ,   //PHY芯片输入数据有效信号
    input   wire    [1:0]   eth_rx_data_r   ,   //PHY芯片输入数据

    output  wire            eth_tx_en_r     ,   //PHY芯片输出数据有效信号
    output  wire    [1:0]   eth_tx_data_r   ,   //PHY芯片输出数据


    output  wire            myphyrst        ,   //PHY芯片复位信号,低电平有效
    output  wire    [5:0]   led,



    output  wire            mdc,
    inout   wire            mdio
);

//********************************************************************//
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//parameter define
parameter   BOARD_MAC   = 48'h12_34_56_78_9a_bc ;   //板卡MAC地址
parameter   BOARD_IP    = 32'hA9_FE_01_17       ;   //板卡IP地址：169.254.1.23
parameter   BOARD_PORT  = 16'd9090              ;   //板卡端口号
parameter   PC_MAC      = 48'h00_2B_67_B5_2A_03 ;   //PC机MAC地址
parameter   PC_IP       = 32'hC0_A8_0F_0F         ;   //PC机IP地址：192.168.15.15
parameter   PC_PORT     = 16'd9090              ;   //PC机端口号

//wire define

wire            clk1m           ;   //1M时钟
wire            clk6m           ;   //6M时钟
wire            rec_end         ;   //单包数据接收完成信号
wire            rec_en          ;   //接收数据使能信号
wire   [31:0]   rec_data        ;   //接收数据
wire   [15:0]   rec_data_num    ;   //接收有效数据字节数
wire            send_end        ;   //发送完成信号
wire            read_data_req   ;   //读数据请求信号
wire            send_en         ;   //数据开始发送信号
wire   [31:0]   send_data       ;   //发送数据
wire            eth_rxdv        ;   //输入数据有效信号(mii)
wire    [3:0]   eth_rx_data     ;   //输入数据(mii)
wire            eth_tx_en       ;   //输出数据有效信号(mii)
wire    [3:0]   eth_tx_data     ;   //输出数据(mii)
wire            fifo_empty      ;   //fifo状态空
wire            fifo_full       ;   //fifo状态满
wire            rtl8201_ready   ;   //rtl8201配置完成
//reg   define
reg             clk_25m         ;   //mii时钟
reg     [5:0]   rled;
wire            rtl8201_flag    ;
wire            mac_flag        ;
wire            ip_flag         ;
wire            receive_right   ;
//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//

//led赋值
assign led = rled;
reg     [23:0]  led_clk;
// always@(posedge sys_clk or negedge sys_rst_n)begin
//     if(sys_rst_n == 1'b0)begin
//         rled <= 5'b00001;
//         led_clk <= 24'd0;
//     end

//     else if(rtl8201_flag == 1'b1)begin
//         rled <= 5'b10101;
//     end

//     else begin
//         led_clk <= led_clk + 24'd1;
//         if(led_clk == 24'd0)begin
//             rled <= {rled[4:0],rled[5]};
//         end
//     end
// end


always@(posedge sys_clk or negedge sys_rst_n)begin
    if(sys_rst_n == 1'b0)begin
        rled <= 5'b00001;
        led_clk <= 24'd0;
    end

    else if(receive_right == 1'b1)begin
        rled <= 5'b10101;
    end
    // else        
    //     rled <= 5'b11111;
end











//clk_25m:mii时钟
always@(negedge eth_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        clk_25m <=  1'b0;
    else
        clk_25m <=  ~clk_25m;

//********************************************************************//
//*************************** Instantiation **************************//
//********************************************************************//

//------------- rmii_to_mii_inst -------------
rmii_to_mii rmii_to_mii_inst
(
    .eth_rmii_clk   (eth_clk        ),  //rmii时钟
    .eth_mii_clk    (clk_25m        ),  //mii时钟
    .sys_rst_n      (sys_rst_n      ),  //复位信号
    .rx_dv          (eth_rxdv_r     ),  //输入数据有效信号(rmii)
    .rx_data        (eth_rx_data_r  ),  //输入数据(rmii)

    .eth_rx_dv      (eth_rxdv       ),  //输入数据有效信号(mii)
    .eth_rx_data    (eth_rx_data    )   //输入数据(mii)
);

//------------- eth_udp_inst -------------
eth_udp_mii
#(
    .BOARD_MAC      (BOARD_MAC      ),  //板卡MAC地址
    .BOARD_IP       (BOARD_IP       ),  //板卡IP地址
    .BOARD_PORT     (BOARD_PORT     ),  //板卡端口号
    .PC_MAC         (PC_MAC         ),  //PC机MAC地址
    .PC_IP          (PC_IP          ),  //PC机IP地址
    .PC_PORT        (PC_PORT        )   //PC机端口号
)
eth_udp_mii_inst
(
    .eth_rx_clk     (clk_25m        ),  //mii时钟,接收
    .sys_rst_n      (sys_rst_n      ),  //复位信号,低电平有效
    .eth_rxdv       (eth_rxdv       ),  //输入数据有效信号(mii)
    .eth_rx_data    (eth_rx_data    ),  //输入数据(mii)
    .eth_tx_clk     (clk_25m        ),  //mii时钟,发送
    .send_en        (rec_end        ),  //开始发送信号
    .send_data      (send_data      ),  //发送数据
    .send_data_num  (rec_data_num   ),  //发送有效数据字节数

    .send_end       (send_end       ),  //单包数据发送完成信号
    .read_data_req  (read_data_req  ),  //读数据请求信号
    .rec_end        (rec_end        ),  //单包数据接收完成信号
    .rec_en         (rec_en         ),  //接收数据使能信号
    .rec_data       (rec_data       ),  //接收数据
    .rec_data_num   (rec_data_num   ),  //接收有效数据字节数
    .eth_tx_en      (eth_tx_en      ),  //输出数据有效信号(mii)
    .eth_tx_data    (eth_tx_data    ),  //输出数据(mii)
    .eth_rst_n      (eth_rst_n      ),  //复位信号,低电平有效
    .receive_right  (receive_right  ),  //判断接收到的数据是否正确标志
    .mac_flag       (mac_flag       ),
    .ip_flag        (ip_flag        )
);

//------------- mii_to_rmii_inst -------------
mii_to_rmii mii_to_rmii_inst
(
    .eth_mii_clk    (clk_25m        ),  //mii时钟
    .eth_rmii_clk   (eth_clk        ),  //rmii时钟
    .sys_rst_n      (sys_rst_n      ),  //复位信号
    .tx_dv          (eth_tx_en      ),  //输出数据有效信号(mii)
    .tx_data        (eth_tx_data    ),  //输出有效数据(mii)

    .eth_tx_dv      (eth_tx_en_r    ),  //输出数据有效信号(rmii)
    .eth_tx_data    (eth_tx_data_r  )   //输出数据(rmii)
);




//------------- fifo_2048x32_inst -------------
//fifo模块，用于缓存单包数据
fifo_2048x32    fifo_2048x32_inst(
	.Data   (rec_data       ),              //input [31:0] Data
	.Reset  (1'b0           ),              //input Reset
	.WrClk  (clk_25m        ),              //input WrClk
	.RdClk  (clk_25m        ),              //input RdClk
	.WrEn   (rec_en         ),              //input WrEn
	.RdEn   (read_data_req  ),              //input RdEn


	.Q      (send_data      ),              //output [31:0] Q
	.Empty  (Empty_o        ),              //output Empty
	.Full   (Full_o         )               //output Full
);

//pll-1M时钟
pll_1m pll_1m_0(
    .clkout     (clk6m       ),             //output clkout
    .clkoutd    (clk1m       ),             //output clkoutd
    .clkin      (sys_clk     )              //input clkin
);

//rtl8201_initialize模块，用于初始化rtl8201芯片
rtl8201_initialize  rtl8201_initialize_inst0
(
    .sys_clk        (clk1m),
    .sys_rst        (sys_rst_n),



    .rtl8201_flag   (rtl8201_flag),

    .ready          (rtl8201_ready),
    .phyrst         (myphyrst),
    .mdc            (mdc),
    .mdio           (mdio)

);

endmodule